package cn.taobaoke.restful.controller;

import cn.taobaoke.restful.domain.AgentRepository;
import cn.taobaoke.restful.domain.PIDEntity;
import cn.taobaoke.restful.domain.ProductEntity;
import cn.taobaoke.restful.exception.TBKException;
import cn.taobaoke.restful.service.*;
import cn.taobaoke.restful.util.GsonUtil;
import cn.taobaoke.restful.util.OkHttpUtil;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Map;
import java.util.concurrent.*;

/**
 * ThirdPartyController类. +-----------------------------------------------------------------------------------------------+
 * |类名称: ThirdPartyController | |创建时间: 4/23/17
 * | |功能简介:
 * | |参考链接:
 * | +-----------------------------------------------------------------------------------------------+
 *
 * @author luch
 */
@RestController
@RequestMapping("/{domain}/{domainId}/api/third")
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class ThirdPartyController extends BaseController {

    private static final String SHORT_SERVER_HOST = "http://47.93.227.191:8181";

    @PostMapping("/shortLink")
    public String shortLink(@PathVariable String domain, @RequestBody Map<String, Object> map) throws IOException {
        String link = (String) map.get("llink");

        if (link == null || link.isEmpty()) {
            throw new TBKException("llink 不能为空");
        }
        String shortLinkAPI = String.format("%s/cwl/link/lslink", SHORT_SERVER_HOST);
        return OkHttpUtil.DEFAULT.postJson(shortLinkAPI, GsonUtil.getJsonString(map));
    }

    //导购
    @PostMapping("/tkls/{agentId}/shareProduct")
    public Result shareProduct(@PathVariable String domain, @PathVariable Long domainId, @PathVariable Long agentId, @RequestBody Map<String, Object> map) {
        String content = (String) map.get("content");
        if (content == null) throw new TBKException("content参数不能为空");
        String items[] = content.split("￥");
        if (items.length < 3) {
            throw new TBKException("未识别到淘口令");
        }
        String taokoulin = items[1];


        Map<String, Object> config = globalConfigService.queryConfig(domainId);
        String pid = (String) config.getOrDefault(cn.taobaoke.restful.util.Constants.ADMIN_PID, "");

        if (agentId != null) {
            PIDEntity pidEntity = pidService.getPidByAgentId(agentId, domainId);
            if (pidEntity == null) {
                throw new TBKException("推广群对应的pid为空");
            }
            pid = pidEntity.getPid();
        }

        try {
            Map retMap = taobaoApi.tranlateTaokoulinToPid(taokoulin, pid, domain);
            return wrapObj(retMap);
        } catch (IOException e) {
            logger.error("导寻失败", e);
            new TBKException("导寻失败", e);
        } catch (Exception e) {
            logger.error("导寻失败", e);
            new TBKException("导寻失败", e);
        }
        throw new TBKException("导寻失败");
    }


    @PostMapping("/tkls/groupTkl")
    public Result getTklByGroupNameAndProductId(@PathVariable String domain, @PathVariable Long domainId, @RequestBody Map<String, Object> map) {

        String groupName = (String) map.get("groupName");
        String link = (String) map.get("link");

        if (groupName == null || link == null) {
            throw new TBKException("groupName or link cannot be empty.");
        }
        groupName = groupService.clearGroupName(groupName);
        String pid = groupService.queryPidForWxGroup(groupName, domainId);

        if (pid == null) {
            throw new TBKException("推广群对应的pid为空");
        }

        // 将原来链中
        // pid=mm_14679296_14892152_57994304
        int left = link.indexOf("pid=");
        int right = -1;
        if (left > 0) {
            right = link.indexOf("&", left);
            if (right > 0) {
                link = link.substring(0, left + 4) + pid + link.substring(right);
            } else {
                link = link.substring(0, left + 4) + pid;
            }
        } else {
            link = "&pid=" + pid;
        }
        // link += "&pid=" + pid;

        logger.info("taobaoApi.getTaokoulin: Link={}", link);
        String tkl = taobaoApi.getTaokoulin(link, domain);

        logger.info("[POST] /{}/api/third/tkls/groupTkl pid={}, tkl={}", domain, pid, tkl);
        return wrapObj(tkl);
    }

    // 获取淘口令形式
    // 1. 发单和搜索的搜索的时候, groupName + productId
    @GetMapping("/tkls/groupTkl")
    public Result getTklByGroupNameAndProductId(@PathVariable String domain, @PathVariable Long domainId, @RequestParam String groupName, @RequestParam Long productId) {

        Future<ProductEntity> future = CompletableFuture.supplyAsync(() -> {
            logger.info("异步查询商品[{}]信息", productId);
            return productService.getProductById(productId, domainId);
        });

        groupName = groupService.clearGroupName(groupName);
        String pid = groupService.queryPidForWxGroup(groupName, domainId);

        ProductEntity productEntity = null;
        try {
            productEntity = future.get(10, TimeUnit.SECONDS);
        } catch (InterruptedException | ExecutionException | TimeoutException e) {
            logger.error("获取商品超时", e);
        }
        // ProductEntity productEntity = productService.getProductById(productId);

        if (pid == null) {
            throw new TBKException("推广群对应的pid为空");
        }
        if (productEntity == null) {
            throw new TBKException("不存在的商品 Id => " + productId);
        }

        String couponUrl = productEntity.getCouponLink() + pid;
        String tkl = taobaoApi.getTaokoulin(couponUrl, domain);

        logger.info("[GET] /{}/api/third/tkls/groupTkl tkl={}", domain, tkl);
        return wrapObj(tkl);
    }


    // 2. 前端页面点击的时候,  agentId/admin + productId
    @GetMapping("/tkls/agentTkl")
    public Result getTbkByAgentOrAdmin(@PathVariable String domain, @PathVariable Long domainId, @RequestParam(required = false) Long agentId, @RequestParam Long productId) {
        Future<ProductEntity> future = CompletableFuture.supplyAsync(() -> {
            logger.info("异步查询商品[{}]信息", productId);
            return productService.getProductById(productId, domainId);
        });

        // ProductEntity productEntity = productService.getProductById(productId);

        Map<String, Object> config = globalConfigService.queryConfig(domainId);
        String pid = (String) config.getOrDefault(cn.taobaoke.restful.util.Constants.ADMIN_PID, "");

        ProductEntity productEntity = null;
        try {
            productEntity = future.get(10, TimeUnit.SECONDS);
        } catch (InterruptedException | ExecutionException | TimeoutException e) {
            logger.error("获取商品超时", e);
        }

        if (agentId != null) {
            PIDEntity pidEntity = pidService.getPidByAgentId(agentId, domainId);
            if (pidEntity == null) {
                throw new TBKException("缺少代理对应的pid为空");
            }
            pid = pidEntity.getPid();
        }
        if (productEntity == null) {
            throw new TBKException("不存在的商品 Id => " + productId);
        }

        String couponUrl = productEntity.getCouponLink() + pid;
        String tkl = taobaoApi.getTaokoulin(couponUrl, domain);

        logger.info("[GET] /{}/api/third/tkls/agentTkl tkl={}, couponUrl={}", domain, tkl, couponUrl);
        return wrapObj(tkl);
    }

    // 3. 转链
    @PostMapping("/tkls/translateContent")
    public Result translateOtherLink(@PathVariable String domain, @RequestBody Map<String, Object> map) {
        Integer agentId = (Integer) map.get("agentId");
        String content = (String) map.get("content");

        return wrapObj("鸿元 Lapps春季英伦哑光雨鞋女士韩版高筒雨靴欧美时尚水鞋胶靴\n原价:79.00￥\n券后:29￥\n复制本条消息" +
                ",拷贝到手机淘宝￥YQIZZtp6vLn￥, 领券购买");
    }

    @PostMapping("/tkls/translateLink")
    public Result getTklByAgentIdAndLink(@PathVariable String domain, @PathVariable Long domainId, @RequestBody Map<String, Object> params) {
        Integer agentId = (Integer) params.get("agentId");
        String link = (String) params.get("link");
        Integer productId = (Integer) params.get("productId");
        String identity = String.format("wx_%s_default_default", domain);

        logger.info("domainId => {} agentId => {} link => {}", domainId, agentId, link);

        if (link == null) {
            return wrapError("link 不能为空");
        }

        Map<String, Object> config = globalConfigService.queryConfig(domainId);
        String pid = (String) config.getOrDefault(cn.taobaoke.restful.util.Constants.ADMIN_PID, "mm_120456523_22078068_73540373");

        logger.info("admin pid = {} domainId => {}", pid, domainId);

        if (agentId != null) {
            PIDEntity pidEntity = pidService.getPidByAgentId(Long.valueOf(agentId), domainId);
            if (pidEntity != null) {
                pid = pidEntity.getPid();
                logger.info("pidEntity != null pid = {}", pid);
            } else {
                logger.info("pidEntity = nill");
            }
        }

        logger.info("taobaoApi.getTaokoulin: Link={}", link);
        String tkl = taobaoApi.getTaokoulinByCouponAndPid(domain, link, pid);
        logger.info("[POST] /{}/api/third/tkls/translateLink tkl={}", domain, tkl);


        logger.info("start to apply plan");
        try {
            innerAPIService.productToApplyPlan(productId, link, identity);
        } catch (IOException e) {
            logger.error("apply plan failed", e);
        }

        return wrapObj(tkl);
    }


    @PostMapping("/tkls/byLink")
    public Result getTklByLink(@PathVariable String domain, @RequestBody Map<String, Object> map) {
        String link = (String) map.get("link");
        if (link == null || link.isEmpty()) {
            throw new TBKException("link参数不能为空");
        }

        if (map.get("pid") == null) {
            throw new TBKException("parameter [pid] required.");
        }
        if (link.length() - link.indexOf("pid=") <= 5) {
            link = link + map.get("pid").toString();
        }
        String tkl = taobaoApi.getTaokoulin(link, domain);

        // PID 合法性进行验证!!!
        return wrapObj(tkl);
    }

    private String handleTitle(final String str) {
        int index = str.indexOf("】");
        String tmpStr = str;
        if (index != -1) {
            tmpStr = str.substring(index + 1);
        }
        String[] tokens = tmpStr.split(" ");
        return Arrays.stream(tokens).max(Comparator.comparing(String::length)).orElse("");
    }


//    https://detail.tmall.com/item.htm?id=534198354462&ali_trackid=2:mm_120456523_22556802_74748128:1492928831_310_1792599784&spm=a311n.8189758/a.90302110.002&sku_properties=-1:-1
//    https://detail.tmall.com/item.htm?id=534198354462&ali_trackid=2:mm_120456523_22556802_75596235:1492928879_3k2_322554236&sku_properties=-1:-1

    @GetMapping("/iosApp/checkIn")
    public Result iosAppCheckIn() {
        return wrapObj(false);
    }


    private final
    @NonNull
    GlobalConfigService globalConfigService;

    private final
    @NonNull
    ProductService productService;

    private final
    @NonNull
    WxGroupService groupService;

    private final
    @NonNull
    PIDService pidService;

    private final
    @NonNull
    TaobaoApi taobaoApi;

    private final
    @NonNull
    InnerAPIService innerAPIService;

    private static Logger logger = LogManager.getLogger(ThirdPartyController.class);
}
